package com.restjplat.core.webserver; import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.springframework.beans.TypeMismatchException; import org.springframework.beans.factory.InitializingBean; import org.springframework.http.HttpStatus; import org.springframework.http.converter.HttpMessageNotReadableException; import org.springframework.stereotype.Component; import org.springframework.web.HttpMediaTypeNotAcceptableException; import org.springframework.web.HttpMediaTypeNotSupportedException; import org.springframework.web.HttpRequestMethodNotSupportedException; import org.springframework.web.bind.MissingServletRequestParameterException; import org.springframework.web.servlet.mvc.multiaction.NoSuchRequestHandlingMethodException; @Component public class DefaultRestErrorResolver implements RestErrorResolver,InitializingBean{ /** * 预先定义的所有异常类型 */ private Map<String, String> exceptionMappings = Collections.emptyMap(); /** * 配置文件中自定义扩展错误 */ private Map<String, String> exceptionMappingDefinitions = Collections.emptyMap(); @Override public RestError resolveError(HttpServletRequest request, Object handler, Exception ex) { RestError error = this.buildError(ex, request); return error; } private RestError buildError(Exception ex, HttpServletRequest request) { RestError error = new RestError(); error.setStatus(this.getHttpStatusByEx(ex));// 设置http状态 //RestServiceException 包含有错误code if(ex instanceof RestServiceException){ int errorCode = ((RestServiceException) ex).getErrorCode(); error.setErrorCode(RestErrorCode.valueOf(errorCode)); } else error.setErrorCode(RestErrorCode.valueOf(998)); error.setMsg(ex.getMessage()); if(null != request){ error.setFromUri(request.getRequestURI()); }else error.setFromUri("unknowurl"); return error; } private HttpStatus getHttpStatusByEx(Exception ex){ if(this.exceptionMappingDefinitions.containsKey(ex.getClass().getName())){ return HttpStatus.valueOf(Integer.parseInt(this.exceptionMappingDefinitions.get(ex.getClass() .getName()))); } else return HttpStatus.INTERNAL_SERVER_ERROR; } @Override public void afterPropertiesSet() throws Exception { //初始化所有预先定义的错误 this.exceptionMappings = createDefaultExceptionMappingDefinitions(); //如果存在自定义的错误,添加到预定义错误中 if (this.exceptionMappingDefinitions != null && !this.exceptionMappingDefinitions.isEmpty()) { this.exceptionMappings.putAll(this.exceptionMappingDefinitions); } } /** * 将spring中的http状态和异常互相对应 参考 spring的defaultExceptionHandler实现类似 * * @return */ private final Map<String, String> createDefaultExceptionMappingDefinitions() { Map<String, String> m = new LinkedHashMap<String, String>(); // 400 applyDef(m, HttpMessageNotReadableException.class, HttpStatus.BAD_REQUEST); applyDef(m, MissingServletRequestParameterException.class, HttpStatus.BAD_REQUEST); applyDef(m, TypeMismatchException.class, HttpStatus.BAD_REQUEST); applyDef(m, "javax.validation.ValidationException", HttpStatus.BAD_REQUEST); // 404 applyDef(m, NoSuchRequestHandlingMethodException.class, HttpStatus.NOT_FOUND); applyDef(m, "org.hibernate.ObjectNotFoundException", HttpStatus.NOT_FOUND); // 405 applyDef(m, HttpRequestMethodNotSupportedException.class, HttpStatus.METHOD_NOT_ALLOWED); // 406 applyDef(m, HttpMediaTypeNotAcceptableException.class, HttpStatus.NOT_ACCEPTABLE); // 409 applyDef(m, "org.springframework.dao.DataIntegrityViolationException", HttpStatus.CONFLICT); // 415 applyDef(m, HttpMediaTypeNotSupportedException.class, HttpStatus.UNSUPPORTED_MEDIA_TYPE); return m; } private void applyDef(Map<String, String> m, Class clazz, HttpStatus status) { applyDef(m, clazz.getName(), status); } private void applyDef(Map<String, String> m, String key, HttpStatus status) { m.put(key, status.value() + ""); } public Map<String, String> getExceptionMappings() { return exceptionMappings; } public void setExceptionMappings(Map<String, String> exceptionMappings) { this.exceptionMappings = exceptionMappings; } public Map<String, String> getExceptionMappingDefinitions() { return exceptionMappingDefinitions; } public void setExceptionMappingDefinitions( Map<String, String> exceptionMappingDefinitions) { this.exceptionMappingDefinitions = exceptionMappingDefinitions; } }